<template>
  <!-- 页面最外层容器 -->
  <el-container class="visualization-container">
    <!-- 左侧可变宽度面板 -->
    <el-aside class="aside-panel" :style="{ width: asideWidth + 'px' }">
      <div class="aside-content">
        <!-- STEP 1: 选择工单 -->
        <div class="step-title">
          <span>STEP 1. 选择工单</span>
        </div>
        <div class="step-body">
          <el-button :class="selectedOrders.length > 0 ? 'idoo-details-add' : 'btn-primary'" type="primary" size="small"
            @click="switchPanel('orderSelection')" style="margin-top: 10px; width: 150px;">
            {{ selectedOrders.length > 0 ? `已选择${selectedOrders.length}条工单` : '选择工单' }}
          </el-button>
        </div>
        <el-divider class="custom-divider" />

        <!-- STEP 2: 约束配置 -->
        <div class="step-title">
          <span>STEP 2. 约束配置</span>
        </div>
        <div class="step-body">
          <el-button type="primary" class="btn-primary" size="small" @click="handleAddConstraint">
            + 添加约束
          </el-button>
        </div>

        <transition-group name="constraint-motion" tag="div">
          <div v-for="(constraint, index) in constraints" :key="constraint.id" class="constraint-item"
            :class="{ active: selectedConstraintIndex === index }" @click="selectConstraint(index, constraint)"
            @dblclick.stop="startTitleEdit(index)">
            <div class="constraint-title">
              <template v-if="editIndex !== index">
                <div class="constraint-title-left">
                  <el-checkbox 
                    v-model="constraint.checked" 
                    @click.stop 
                    @change="handleConstraintCheckChange(constraint)"
                    class="constraint-checkbox"
                  />
                  <span class="constraint-title-text">{{ constraint.title }}</span>
                </div>
                <el-button type="primary" size="small" @click.stop="deleteConstraint(index)"
                  style="background-color: #714B67; border-color: #714B67;">删除</el-button>
              </template>
              <template v-else>
                <el-input :ref="'titleInput' + index" v-model="constraint.title" size="small" @blur="finishTitleEdit"
                  @keydown.enter="finishTitleEdit"></el-input>
              </template>
            </div>
          </div>
        </transition-group>
      </div>
      <div class="aside-footer">
        <el-button 
          type="primary" 
          :disabled="showLoading"
          :loading="showLoading"
          @click="handleGeneratePlan"
        >
          {{ showLoading ? '正在执行...' : '推演方案 ->' }}
        </el-button>
      </div>
    </el-aside>

    <!-- 分隔条，可拖拽，用于调整asidePanel宽度 -->
    <div class="resizer" @mousedown="startResize"></div>

    <!-- 右侧主面板 -->
    <el-main class="main-panel">
      <!-- 订单管理面板 -->
      <OrderManagementPanel
        v-if="activePanel === 'orderSelection'"
        :selected-orders="selectedOrders"
        :unselected-orders="unselectedOrders"
        :loading="showLoading"
        @update-selected-orders="handleUpdateSelectedOrders"
        @data-sync-requested="handleDataSyncRequested"
        @orders-imported="handleOrdersImported"
        @selection-changed="handleOrderSelectionChanged"
      />

      <!-- 约束配置面板 -->
      <ConstraintConfigPanel
        ref="constraintConfigPanelRef"
        v-if="activePanel === 'constraints' && selectedConstraintItem?.id"
        :key="`constraint-${selectedConstraintItem?.id}-${selectedConstraintIndex}`"
        :selected-constraint-index="selectedConstraintIndex"
        :constraint-config-id="selectedConstraintItem?.id"
        :constraint-config-title="selectedConstraintItem?.title"
        :is-new-constraint="isCurrentConstraintNew"
        :selected-orders="selectedOrders"
        :loading="showLoading"
        @constraint-status-checked="handleConstraintStatusChecked"
        @constraint-loaded="handleConstraintLoaded"
        @constraint-load-failed="handleConstraintLoadFailed"
        @config-changed="handleConfigChanged"
        @config-validated="handleConfigValidated"
        @config-saved="handleConfigSaved"
      />

      <!-- 空状态提示 -->
      <div v-if="activePanel === 'constraints' && (!selectedConstraintItem?.id || selectedConstraintIndex === null)" class="empty-main-state">
        <div class="empty-content">
          <el-icon size="64" color="#c0c4cc">
            <Document />
          </el-icon>
          <h3>Scheduling Simulator</h3>
          <h4>排程计划模拟器</h4>
          <p>请从左侧选择功能开始使用：</p>
          <ul class="feature-list">
            <li>选择工单 - 管理和导入工单数据</li>
            <li>约束配置 - 设置排程参数和规则</li>
          </ul>
        </div>
      </div>
    </el-main>
  </el-container>

  <!-- 全屏loading组件 -->
  <FullScreenLoading :visible="showLoading" :totalDelay="100000" :typingSpeed="200" :messages="[loadingText]"
    :text="loadingText" />
</template>

<script>
import { ref, nextTick, getCurrentInstance, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Document } from '@element-plus/icons-vue'
import FullScreenLoading from '@/idoo-core/loading/streaming-loading/FullScreenLoading.vue'
import OrderManagementPanel from '@/components/visualiszation/OrderManagementPanel.vue'
import ConstraintConfigPanel from '@/components/visualiszation/ConstraintConfigPanel.vue'
import { orderApi } from '@/api/order'
import { basicProductApi } from '@/api/basicProduct'
import { schedulingPlanApi } from '@/api/schedulingPlan'
import { constraintApi } from '@/api/constraint'
import {
  asideConfig,
  PanelType,
  ErrorMessages,
  LoadingMessages,
  updateProductOptions
} from './VisualizationConfig'

export default {
  name: 'Visualization',
  components: {
    FullScreenLoading,
    OrderManagementPanel,
    ConstraintConfigPanel,
    Document
  },
  setup() {
    // 路由实例
    const router = useRouter()
    
    // ============== 1. 公共或全局状态 ==============

    // 当前激活的tab，可用于后续扩展；目前默认设置为 'overview'
    const activeTab = ref('overview')
    // 区分是选择工单(orderSelection)还是约束配置(constraints)
    const activePanel = ref(PanelType.ORDER_SELECTION)

    // 是否显示全屏loading
    const showLoading = ref(false)
    const loadingText = ref('')

    // ============== 2. 工单相关 ==============

    // 待排程工单列表
    const unselectedOrders = ref([])

    // 已选工单列表
    const selectedOrders = ref([])

    // 待排程工单表格引用（现在在子组件中）
    // const unselectedOrderTableRef = ref()

    // 待排程工单勾选行（现在在子组件中）
    // const selectedRows = ref([])

    // 产品列表数据
    const productList = ref([])

    /**
     * 切换面板
     * @param {String} panel - 'orderSelection' 或 'constraints'
     * 如果点击 'orderSelection'，则隐藏约束内容
     */
    const switchPanel = (panel) => {
      activePanel.value = panel
      
      // 只有切换到订单选择时才清空约束选择，避免不必要的状态重置
      if (panel === PanelType.ORDER_SELECTION) {
        selectedConstraintIndex.value = null
        selectedConstraintItem.value = {}
        isCurrentConstraintNew.value = false
      }
    }

    // 工单操作相关方法已移至子组件 SchedulingMainPanel.vue
    
    /**
     * 处理子组件的工单更新事件
     */
    const handleUpdateSelectedOrders = (orderData) => {
      selectedOrders.value = orderData.selectedOrders
      unselectedOrders.value = orderData.unselectedOrders
    }

    /**
     * 处理数据同步请求事件
     */
    const handleDataSyncRequested = async () => {
      showLoading.value = true
      loadingText.value = '正在同步数据...'
      
      try {
        // 重新加载已选择和未选择的工单数据
        await loadSelectedOrders()
      } catch (error) {
        ElMessage.error('数据同步失败')
      } finally {
        showLoading.value = false
      }
    }

    /**
     * 处理工单导入事件
     */
    const handleOrdersImported = (importResult) => {
      if (importResult.type === 'success') {
        // 刷新工单数据
        loadSelectedOrders()
      }
    }

    /**
     * 处理工单选择变化事件
     */
    const handleOrderSelectionChanged = (selectionData) => {
      // 工单选择变化处理
    }

    /**
     * 处理约束配置变化事件
     */
    const handleConfigChanged = (configData) => {
      // 配置变化处理
    }

    /**
     * 处理配置验证事件
     */
    const handleConfigValidated = (validationResult) => {
      // 配置验证结果处理
    }

    /**
     * 处理配置保存事件
     */
    const handleConfigSaved = (saveResult) => {
      console.log('💾 约束配置保存结果:', {
        constraintId: saveResult.constraintId,
        success: saveResult.success,
        timestamp: new Date().toISOString()
      })
      
      if (!saveResult.success) {
        ElMessage.error('配置保存失败')
      }
    }

    // ============== 3. 约束配置相关 ==============

    // 约束配置列表
    const constraints = ref([])

    // 当前选中的约束配置索引
    const selectedConstraintIndex = ref(null)

    // 当前选中的约束配置对象
    const selectedConstraintItem = ref({})

    // 当前约束是否为新创建的约束
    const isCurrentConstraintNew = ref(false)

    // 双击标题时编辑的索引
    const editIndex = ref(null)

    // 约束配置面板的引用
    const constraintConfigPanelRef = ref(null)

    // 加载约束列表
    const loadConstraints = async () => {
      try {
        const res = await constraintApi.list()
        const list = res?.data || []
        constraints.value = (list || []).map(item => ({
          id: item.id,
          title: item.title || item.constraintName || '新增约束',
          checked: false  // 默认不选中
        }))
        
        console.log('📋 加载约束列表:', {
          count: constraints.value.length,
          constraints: constraints.value,
          timestamp: new Date().toISOString()
        })
        
        // 只在没有选中约束或约束面板未激活时才自动选择第一个
        if (constraints.value.length > 0 && 
            (selectedConstraintIndex.value === null || activePanel.value !== PanelType.CONSTRAINTS)) {
          await selectConstraint(0, constraints.value[0])
        } else if (constraints.value.length === 0) {
          // 清空选择状态
          selectedConstraintIndex.value = null
          selectedConstraintItem.value = {}
          isCurrentConstraintNew.value = false
        }
      } catch (e) {
        console.error('加载约束列表失败:', e)
        ElMessage.error('加载约束列表失败')
        constraints.value = []
        selectedConstraintIndex.value = null
        selectedConstraintItem.value = {}
        isCurrentConstraintNew.value = false
      }
    }

    /**
     * 处理约束 checkbox 变化
     */
    const handleConstraintCheckChange = (constraint) => {
      console.log('📝 约束选中状态变化:', {
        constraintId: constraint.id,
        constraintTitle: constraint.title,
        checked: constraint.checked,
        timestamp: new Date().toISOString()
      })
    }

    /**
     * 点击"添加约束"：输入名称并调用后端新增
     */
    const handleAddConstraint = async () => {
      try {
        const { value } = await ElMessageBox.prompt('请输入约束配置名称', '新增约束', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          inputValue: '新增约束',
          inputPattern: /\S+/,
          inputErrorMessage: '名称不能为空'
        })
        
        showLoading.value = true
        loadingText.value = '正在创建约束配置...'
        
        const resp = await constraintApi.create(value)
        
        if (resp && resp.success && resp.data) {
          // 根据API返回格式，data 直接是约束ID字符串
          const constraintId = resp.data
          const item = { 
            id: constraintId, 
            title: value,  // 使用用户输入的名称作为标题
            checked: false  // 默认不选中
          }
          
          // 添加到约束列表
          constraints.value.push(item)
          
          // 标记为新创建的约束
          isCurrentConstraintNew.value = true
          
          // 自动选择新创建的约束索引
          const newIndex = constraints.value.length - 1
          
          // 原子性更新状态，避免调用 selectConstraint 可能重置 isCurrentConstraintNew
          selectedConstraintIndex.value = newIndex
          selectedConstraintItem.value = { ...item }
          activePanel.value = PanelType.CONSTRAINTS
          
        } else {
          ElMessage.error(resp?.message || '新增约束失败')
        }
      } catch (err) {
        if (err !== 'cancel' && err !== 'close') {
          ElMessage.error('新增约束失败')
        }
      } finally {
        showLoading.value = false
      }
    }

    /**
     * 删除约束配置：二次确认后调用后端删除
     */
    const deleteConstraint = async (index) => {
      const item = constraints.value[index]
      if (!item?.id) {
        constraints.value.splice(index, 1)
        return
      }
      try {
        await ElMessageBox.confirm(`确定要删除约束【${item.title}】吗？`, '删除确认', {
          type: 'warning',
          confirmButtonText: '删除',
          cancelButtonText: '取消'
        })
        await constraintApi.remove(item.id)
        constraints.value.splice(index, 1)
        
        // 重置新建状态
        isCurrentConstraintNew.value = false
        
        if (constraints.value.length > 0) {
          const newIndex = Math.min(index, constraints.value.length - 1)
          await selectConstraint(newIndex, constraints.value[newIndex])
        } else {
          selectedConstraintIndex.value = null
          selectedConstraintItem.value = {}
        }
      } catch (err) {
        if (err !== 'cancel' && err !== 'close') {
          ElMessage.error('删除失败')
        }
      }
    }

    /**
     * 选择约束配置
     * @param {Number} index
     * @param {Object} item
     */
    const selectConstraint = async (index, item) => {
      console.log('🔄 切换约束规则:', {
        constraintIndex: index,
        constraintId: item?.id,
        constraintTitle: item?.title,
        timestamp: new Date().toISOString()
      })
      
      // 验证输入参数
      if (!item?.id) {
        ElMessage.warning('约束配置数据无效')
        return
      }
      
      // 避免重复选择相同约束
      if (selectedConstraintIndex.value === index && 
          selectedConstraintItem.value?.id === item.id &&
          activePanel.value === PanelType.CONSTRAINTS) {
        return
      }
      
      // 原子性更新所有相关状态
      try {
        // 重置新建状态（子组件会重新检查并通知父组件真实状态）
        isCurrentConstraintNew.value = false
        
        // 同步更新状态
        selectedConstraintIndex.value = index
        selectedConstraintItem.value = { ...item } // 使用浅拷贝避免引用问题
        activePanel.value = PanelType.CONSTRAINTS
      } catch (error) {
        ElMessage.error('切换约束配置失败')
      }
    }

    /**
     * 双击标题开始编辑
     * @param {Number} index
     */
    const startTitleEdit = (index) => {
      editIndex.value = index
      nextTick(() => {
        // we access the ref of the newly toggled input
        const inst = getCurrentInstance()
        const inputComp = inst.proxy.$refs['titleInput' + index]
        if (inputComp) {
          inputComp.focus()
        }
      })
    }

    /**
     * 结束标题编辑，恢复正常显示
     */
    const finishTitleEdit = () => {
      editIndex.value = null
    }

    // ============== 4. 可拖拽左侧aside宽度 ==============

    // aside 初始宽度
    const asideWidth = ref(asideConfig.defaultWidth)

    // 是否正在拖拽
    const isResizing = ref(false)

    // 上一次鼠标坐标，用于计算拖拽距离
    const lastClientX = ref(0)

    /**
     * 按下鼠标，开始拖拽
     * @param e
     */
    const startResize = (e) => {
      isResizing.value = true
      lastClientX.value = e.clientX
      document.addEventListener('mousemove', handleResizing)
      document.addEventListener('mouseup', stopResize)
    }

    /**
     * 拖拽过程中持续更新 aside 宽度
     * @param e
     */
    const handleResizing = (e) => {
      if (!isResizing.value) return
      const deltaX = e.clientX - lastClientX.value
      asideWidth.value = Math.max(asideConfig.minWidth, asideWidth.value + deltaX)
      lastClientX.value = e.clientX
    }

    /**
     * 鼠标松开，结束拖拽
     */
    const stopResize = () => {
      isResizing.value = false
      document.removeEventListener('mousemove', handleResizing)
      document.removeEventListener('mouseup', stopResize)
    }

    // ============== 5. 子组件事件处理 ==============

    /**
     * 处理约束配置状态检查事件
     */
    const handleConstraintStatusChecked = (statusData) => {
      // 更新当前约束的新建状态
      isCurrentConstraintNew.value = statusData.isNewConstraint
    }

    /**
     * 处理约束配置加载成功事件
     */
    const handleConstraintLoaded = (data) => {
      // 约束配置加载成功处理
    }

    /**
     * 处理约束配置加载失败事件
     */
    const handleConstraintLoadFailed = (error) => {
      isCurrentConstraintNew.value = false  // 加载失败时重置状态
    }

    // ============== 6. Excel导入配置 ==============

    // Excel导入处理已移至子组件 SchedulingMainPanel.vue

    /**
     * 加载产品数据
     */
    const loadProductData = async () => {
      try {
        const response = await basicProductApi.getProductsByCurrentTenant()
        
        if (response && response.data) {
          productList.value = response.data
          // 更新表格列配置中的产品选项
          updateProductOptions(response.data)
        }
      } catch (error) {
        ElMessage.error(ErrorMessages.LOAD_PRODUCTS_FAILED)
      }
    }

    /**
     * 加载已选择工单列表
     */
    const loadSelectedOrders = async () => {
      try {
        showLoading.value = true
        loadingText.value = LoadingMessages.LOADING_ORDERS

        const response = await orderApi.getUnselectedOrders()
        
        if (response && response.data) {
          // 为每条数据添加必要的字段，加载到已选择工单列表
          selectedOrders.value = response.data.map(order => ({
            ...order,
            _id: order.id || order._id || `${order.apsOrderCode || order.apsOrderCode}-${order.orderCode}`,
            apsOrderCode: order.apsOrderCode || order.apsOrderCode,
            orderCode: order.orderCode,
            productCode: order.productCode,
            deliveryDate: order.deliveryDate,
            quantity: order.quantity,
            priority: order.priority || '中'
          }))
          
        }
      } catch (error) {
        ElMessage.error(ErrorMessages.LOAD_ORDERS_FAILED)
      } finally {
        showLoading.value = false
      }
    }

    /**
     * 初始化加载数据
     */
    const initializeData = async () => {
      // 先加载产品数据，再加载已选择的工单数据
      await loadProductData()
      await loadSelectedOrders()
      // 初始化加载约束列表
      await loadConstraints()
      // 待排程工单初始为空，由用户手动添加
    }

    // 组件挂载时初始化数据
    onMounted(() => {
      initializeData()
    })

    // ============== 7. 配置数据管理方法（现在在子组件中处理） ==============
    
    // 数据管理相关方法已移至子组件 SchedulingMainPanel.vue

    // 配置数据加载、验证、重置等方法已移至子组件 SchedulingMainPanel.vue

    /**
     * 等待文字完全显示
     * 优化：限制最大等待时间，避免过长等待
     */
    const waitForTextDisplay = async (text, typingSpeed = 30, maxDelay = 300) => {
      const delay = Math.min(text.length * typingSpeed, maxDelay)
      await new Promise(resolve => setTimeout(resolve, delay))
    }

    /**
     * 验证并保存单个约束配置
     */
    const validateAndSaveConstraint = async (constraint, index, total) => {
      const typingSpeed = 30  // 优化：从 200 降低到 30，加快响应速度
      const maxDelay = 200    // 最大等待时间限制
      
      try {
        // 1. 更新 loading 文本：正在验证
        const validateText = `正在验证约束配置 (${index + 1}/${total}): ${constraint.title}...`
        loadingText.value = validateText
        console.log(`🔍 ${validateText}`)
        
        // 等待文字完全显示（优化：减少等待时间）
        await waitForTextDisplay(validateText, typingSpeed, maxDelay)
        
        // 2. 切换到该约束配置
        const constraintIndex = constraints.value.findIndex(c => c.id === constraint.id)
        if (constraintIndex === -1) {
          throw new Error(`未找到约束配置: ${constraint.title}`)
        }
        
        // 切换约束并等待面板加载
        await selectConstraint(constraintIndex, constraint)
        
        // 等待 DOM 更新和组件加载（优化：从 500ms 降低到 150ms）
        await nextTick()
        await new Promise(resolve => setTimeout(resolve, 150))
        
        // 3. 验证配置
        if (!constraintConfigPanelRef.value) {
          throw new Error(`约束配置面板未加载: ${constraint.title}`)
        }
        
        const isValid = await constraintConfigPanelRef.value.validateAllConfig()
        if (!isValid) {
          throw new Error(`约束配置验证失败: ${constraint.title}，请检查配置项`)
        }
        
        console.log(`✅ 约束 ${constraint.title} 验证通过`)
        
        // 4. 更新 loading 文本：正在保存
        const saveText = `正在保存约束配置 (${index + 1}/${total}): ${constraint.title}...`
        loadingText.value = saveText
        console.log(`💾 ${saveText}`)
        
        // 等待文字完全显示（优化：减少等待时间）
        await waitForTextDisplay(saveText, typingSpeed, maxDelay)
        
        // 5. 保存配置
        await constraintConfigPanelRef.value.saveAllConfig()
        
        console.log(`✅ 约束 ${constraint.title} 保存成功`)
        
        return { success: true, constraint }
      } catch (error) {
        console.error(`❌ 处理约束 ${constraint.title} 失败:`, error)
        return { 
          success: false, 
          constraint, 
          error: error.message || '未知错误' 
        }
      }
    }

    /**
     * 推演方案生成
     * 先验证并保存所有选中约束的配置，再生成方案
     * 防重复调用机制：确保当前没有正在执行的推演任务
     * 支持多约束推演
     */
    const handleGeneratePlan = async () => {
      // 🔒 防重复调用检查 - 如果正在加载中，则不允许重复执行
      if (showLoading.value) {
        ElMessage.warning('推演方案正在执行中，请等待完成后再试')
        return
      }

      // 获取所有选中的约束
      const checkedConstraints = constraints.value.filter(c => c.checked)
      
      if (checkedConstraints.length === 0) {
        ElMessage.error('请至少选择一个约束配置')
        return
      }

      if (selectedOrders.value.length === 0) {
        ElMessage.error('请至少选择一个工单')
        return
      }

      // 🚀 开始执行推演流程，设置loading状态
      showLoading.value = true
      const typingSpeed = 30   // 优化：从 200 降低到 30，加快响应速度
      const maxDelay = 200     // 最大等待时间限制
      
      try {
        // 1. 显示初始化文本
        const initText = `准备验证和保存 ${checkedConstraints.length} 个约束配置...`
        loadingText.value = initText
        await waitForTextDisplay(initText, typingSpeed, maxDelay)
        
        // 2. 依次验证并保存每个选中的约束配置
        const saveResults = []
        for (let i = 0; i < checkedConstraints.length; i++) {
          const constraint = checkedConstraints[i]
          const result = await validateAndSaveConstraint(constraint, i, checkedConstraints.length)
          saveResults.push(result)
          
          // 如果保存失败，记录错误但继续处理其他约束
          if (!result.success) {
            console.warn(`⚠️ 约束 ${constraint.title} 处理失败: ${result.error}`)
          }
        }
        
        // 3. 检查是否有失败的约束
        const failedResults = saveResults.filter(r => !r.success)
        if (failedResults.length > 0) {
          const failedNames = failedResults.map(r => r.constraint.title).join('、')
          ElMessage.error(`以下约束配置保存失败: ${failedNames}`)
          return
        }
        
        // 4. 所有约束保存成功，开始生成方案
        const constraintTitles = checkedConstraints.map(c => c.title).join('、')
        const planText = `正在为约束【${constraintTitles}】生成排程方案...`
        loadingText.value = planText
        console.log(`🚀 ${planText}`)
        
        // 等待文字完全显示（优化：减少等待时间）
        await waitForTextDisplay(planText, typingSpeed, maxDelay)
        
        // 5. 构建请求数据列表
        const planDataList = checkedConstraints.map(constraint => ({
          baseParameters: {
            constraintInfo: {
              id: constraint.id,
              title: constraint.title,
              createTime: new Date().toISOString()
            }
          },
          selectedOrderIds: selectedOrders.value.map(order => ({
            id: order.id || order._id,
            apsOrderCode: order.apsOrderCode,
            orderCode: order.orderCode,
            productCode: order.productCode
          })),
          orderCount: selectedOrders.value.length,
          generateTime: new Date().toISOString()
        }))

        console.log('🚀 调用方案推演（多约束）:', {
          constraintCount: checkedConstraints.length,
          constraints: checkedConstraints.map(c => ({ id: c.id, title: c.title })),
          orderCount: selectedOrders.value.length,
          timestamp: new Date().toISOString()
        })
        
        // 6. 调用后端接口，传入约束列表
        const response = await schedulingPlanApi.generatePlan(planDataList)
        
        if (response && response.code === 200) {
          ElMessage.success(`已成功为 ${checkedConstraints.length} 个约束生成排程方案`)
          
          // 7. 跳转到方案比对页面
          const constraintIds = checkedConstraints.map(c => c.id).join(',')
          
          console.log('🚀 跳转到方案比对页面:', {
            constraintIds,
            timestamp: new Date().toISOString()
          })
          
          // 使用 router.push 跳转，并携带约束 ID 列表
          await router.push({
            name: 'PlanComparison',
            query: { constraintIds }
          })
        } else {
          ElMessage.error(response.msg || '排程方案生成失败')
        }
        
      } catch (error) {
        console.error('❌ 推演方案失败:', error)
        // 判断是保存配置失败还是生成方案失败
        if (error.message && error.message.includes('配置') || error.message.includes('验证')) {
          ElMessage.error(error.message || '配置保存失败，请检查配置项后重试')
        } else {
          ElMessage.error('生成排程方案失败，请重试')
        }
      } finally {
        showLoading.value = false
      }
    }

    return {
      // 公共状态
      activeTab,
      activePanel,
      switchPanel,
      showLoading,
      loadingText,
      // 工单相关数据（传给子组件）
      unselectedOrders,
      selectedOrders,
      // 约束配置相关
      constraints,
      selectedConstraintIndex,
      selectedConstraintItem,
      isCurrentConstraintNew,
      constraintConfigPanelRef,
      handleAddConstraint,
      handleConstraintCheckChange,
      deleteConstraint,
      selectConstraint,
      // 标题编辑逻辑
      editIndex,
      startTitleEdit,
      finishTitleEdit,
      // 拖拽相关
      asideWidth,
      startResize,
      // 子组件事件处理 - 订单管理
      handleUpdateSelectedOrders,
      handleDataSyncRequested,
      handleOrdersImported,
      handleOrderSelectionChanged,
      // 子组件事件处理 - 约束配置
      handleConstraintStatusChecked,
      handleConstraintLoaded,
      handleConstraintLoadFailed,
      handleConfigChanged,
      handleConfigValidated,
      handleConfigSaved,
      // 推演方案生成
      handleGeneratePlan,
      // 初始化方法
      initializeData,
      // 产品数据
      productList,
      loadProductData,
      loadSelectedOrders
    }
  }
}
</script>

<style scoped>
.visualization-container {
  height: 87vh;
  display: flex;
}

.aside-panel {
  display: flex;
  flex-direction: column;
  height: calc(90vh - 60px);
}

.aside-content {
  flex: 1;
  overflow-y: auto;
}

.aside-footer {
  text-align: center;
  padding: 10px 0;
  flex-shrink: 0;
  border-top: 1px solid #ebebeb;
}

.step-title {
  width: 80%;
  text-align: center;
  margin-top: 30px;
  font-weight: 600;
  margin-left: auto;
  margin-right: auto;
}

.step-body {
  display: flex;
  justify-content: center;
  margin-top: 10px;
}

.btn-primary {
  width: 150px;
  margin-top: 10px;
}

.custom-divider {
  margin: 20px 0;
  border-style: dotted;
}

.main-panel {
  padding: 20px;
  overflow: auto;
  flex: 1;
}


.empty-main-state {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 500px;
  color: #909399;
}

.empty-content {
  text-align: center;
  max-width: 400px;
}

.empty-content h3 {
  margin: 20px 0 5px;
  color: #409EFF;
  font-weight: 700;
  font-size: 28px;
}

.empty-content h4 {
  margin: 5px 0 20px;
  color: #606266;
  font-weight: 600;
  font-size: 18px;
}

.empty-content p {
  margin: 10px 0;
  font-size: 14px;
}

.feature-list {
  text-align: left;
  margin: 20px 0;
  padding-left: 20px;
}

.feature-list li {
  margin: 8px 0;
  color: #909399;
}

.overview-section,
.production-section,
.settings-section {
  padding: 20px 0;
}

.constraint-motion-enter-active,
.constraint-motion-leave-active {
  transition: all 0.3s ease;
}

.constraint-motion-enter,
.constraint-motion-leave-to {
  opacity: 0;
  transform: translateY(-10px);
}

.constraint-item {
  margin-top: 10px;
  background-color: #f5f5f5;
  padding: 10px;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.2s, border 0.5s ease;
  margin-right: 20px;
  margin-bottom: 10px;
}

.constraint-item:hover {
  background-color: #ebebeb;
}

.constraint-item.active {
  border: 1px solid #714B67;
}

.constraint-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.constraint-title-left {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
  min-width: 0;
}

.constraint-checkbox {
  flex-shrink: 0;
}

.constraint-title-text {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.resizer {
  width: 4px;
  cursor: col-resize;
  background-color: #ccc;
}

.custom-link-button {
  color: black;
  /* System color for links */
  font-weight: 600;
  cursor: pointer;
  text-decoration: underline;
}

.custom-link-button:hover {
  color: rgb(1, 128, 165);
  /* Darker system color on hover */
}
</style>